﻿using SimpleServiceBus.Bus.MessageManagement.Serialization;
using SimpleServiceBus.Configuration;
using SimpleServiceBus.Endpoint;
using SimpleServiceBus.Endpoint.Management;
using SimpleServiceBus.Endpoints.Msmq.Transport;
//using NServiceBus.Unicast.Transport.Msmq.Config;
using SimpleServiceBus.Utilities.ObjectBuilder;
using ConfigMsmqSubscriptionStorage=SimpleServiceBus.Endpoints.Msmq.Transport.Subscriptions.ConfigMsmqSubscriptionStorage;

namespace SimpleServiceBus.Endpoints.Msmq
{
    public class MsmqEndpointConfigurationManager
    {
        public static UnicastMsmqManagedEndpoint CreateManagedEndpointWith<T>(MsmqUnicastOptions options)
            where T : IObjectBuilder
        {
            IObjectBuilder objectBuilder = EndpointConfigurationManager.CreateBuilder<T>();
            ConfigureUnicastMsmqBus(objectBuilder, options);
            EndpointConfigurationManager.ConfigureManagedEndpoint
                <UnicastMsmqManagedEndpoint, EndpointManagementClientService>(objectBuilder);

            return (UnicastMsmqManagedEndpoint) objectBuilder.Build<IMessagingEndpoint>();
        }

        public static UnicastMsmqEndpoint CreateStandardEndpointWith<T>(MsmqUnicastOptions options) where T : IObjectBuilder
        {
            //Create a IoC objectBuilder to construct our environment
            IObjectBuilder objectBuilder = EndpointConfigurationManager.CreateBuilder<T>();

            //Setup the MSMQ MessageBus, Transport, Subscriptions, etc.
            ConfigureUnicastMsmqBus(objectBuilder, options);

            //ConfigureSerialization the Endpoint
            EndpointConfigurationManager.ConfigureEndpoint<UnicastMsmqEndpoint>(objectBuilder);

            //Build the endpoint and return
            return (UnicastMsmqEndpoint) objectBuilder.Build<IMessagingEndpoint>();
        }

        public static void ConfigureUnicastMsmqBus(IObjectBuilder objectBuilder, MsmqUnicastOptions options)
        {
            if (options.SupportSubscriptions)
                ConfigureMsmqSubscriptionStorage(objectBuilder);

            if (options.SerializationMethod == SerializationMethod.Binary)
                ConfigureSerialization.BinarySerializer.With(objectBuilder);
            else if (options.SerializationMethod == SerializationMethod.Xml)
                ConfigureSerialization.XmlSerializer.With(objectBuilder);

            ConfigureMsmqTransport(objectBuilder, options.TransactionalMessageHandling, options.PurgeOnStartup);
            ConfigureUnicastBus(objectBuilder, options.ImpersonateSender);
        }

        public static ConfigMsmqSubscriptionStorage ConfigureMsmqSubscriptionStorage(IObjectBuilder objectBuilder)
        {
            return new ConfigMsmqSubscriptionStorage(objectBuilder);
        }

        public static ConfigMsmqTransport ConfigureMsmqTransport(IObjectBuilder objectBuilder, bool isTransactional,
                                                                 bool purgeOnStartup)
        {
            return new ConfigMsmqTransport(objectBuilder)
                .IsTransactional(isTransactional)
                .PurgeOnStartup(purgeOnStartup);
        }

        public static ConfigUnicastBus ConfigureUnicastBus(IObjectBuilder objectBuilder, bool impersonateSender)
        {
            return new ConfigUnicastBus(objectBuilder)
                .ImpersonateSender(false);
        }
    }
}